package com.im.netty.handler;

import com.alibaba.fastjson.JSONObject;
import com.im.common.MessageEntity;
import com.im.service.MessageService;
import com.im.util.ConstantUtil;
import com.im.util.SpringContextUtil;
import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.*;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: szw
 * @Date: 2021/5/10 17:32
 */
@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("建立连接，通道开启！");
        //添加到channelGroup通道组
        ConstantUtil.addGROUP(ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("断开连接，通道关闭！");
        //添加到channelGroup 通道组
        ConstantUtil.remove(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //首次连接是FullHttpRequest，处理参数 by zhengkai.blog.csdn.net
        if (null != msg && msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;
            String uri = request.uri();

            Map<String, String> paramMap = getUrlParams(uri);
            if (paramMap == null || paramMap.isEmpty() || paramMap.get("clientId") == null) {
                log.info("clientId is null");
                return;
            }
            String clientId = paramMap.get("clientId");
            String targetId = paramMap.get("targetId");
            log.info("绑定 {}", JSONObject.toJSONString(paramMap));
//            UserChannelService.put(clientId, ctx.channel());
            ConstantUtil.put(clientId, targetId, ctx.channel());
            //如果url包含参数，需要处理
            if (uri.contains("?")) {
                String newUri = uri.substring(0, uri.indexOf("?"));
                request.setUri(newUri);
            }

        } else if (msg instanceof TextWebSocketFrame) {
            //正常的TEXT消息类型
            TextWebSocketFrame frame = (TextWebSocketFrame) msg;
            String text = frame.text();
            log.info("正常的TEXT消息类型：" + text);
            // sendAllMessage(frame.text());

            // 获取当前用户用户信息
            String clientId = ConstantUtil.getClientId(ctx.channel().id().asLongText());

            // 推送消息
            MessageEntity build = MessageEntity.builder()
                .sendUserId(clientId)
                .data(text)
                .build();

            SpringContextUtil.getBean(MessageService.class).listen(build);
        }
        super.channelRead(ctx, msg);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
//        log.info("服务器接收到二进制消息.");
//        ByteBuf content = msg.content();
//        content.markReaderIndex();
//        int flag = content.readInt();
//        log.info("标志位:[{}]", flag);
//        content.resetReaderIndex();
//
//        ByteBuf byteBuf = Unpooled.directBuffer(msg.content().capacity());
//        byteBuf.writeBytes(msg.content());
//
//        ctx.writeAndFlush(new BinaryWebSocketFrame(byteBuf));

        //        Channel channel = ctx.channel();
//        //获取客户端传输过来的消息
//        String content = msg.text();
//        log.info("接收的数据：" + content);
//        //1.获取客户端发送来的消息
//        TextWebSocketFrame tws = new TextWebSocketFrame("默认消息");
//        ChannelFuture channelFuture = channel.writeAndFlush(tws);
//        channelFuture.addListener((ChannelFutureListener) future -> {
//            if (future.isSuccess()) { // 写操作完成，并没有错误发生
//                log.info("successful");
//            } else { // 记录错误
//                log.info("error");
//                future.cause().printStackTrace();
//            }
//        });
//        ctx.flush();


//        // 获取当前用户用户信息
//        UserInfo userInfo = ctx.channel().attr(CustomChannelAttribute.CHANNEL_USER_INFO_KEY).get();
//        // 推送消息
//        MessageEntity build = MessageEntity.builder()
//                .sendUserId(userInfo.getUserId())
//                .targetUserId(userInfo.getUserId())
//                .data(content)
//                .build();
//        messageService.push(build);

        /*
        //群发
        TextWebSocketFrame tws = new TextWebSocketFrame(new Date().toString() + "--"
                + ctx.channel().id() + "===》" + content);
        for (Channel channel : clients) {
            channel.writeAndFlush(tws);
        }*/

//      下面这个方法 和上面的for循环 一致
//       clients.writeAndFlush(tws);

    }

    // 握手建立
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // log.info("握手建立");
    }

    // 握手取消
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //ChannelGroup会自动移除
        ctx.channel().close();
        log.info("连接取消");
        ConstantUtil.remove(ctx.channel());
    }


    // 异常处理
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("异常取消:");
        cause.printStackTrace();
        ConstantUtil.remove(ctx.channel());
        ctx.channel().close();
    }

    private void sendAllMessage(String message) {
        //收到信息后，群发给所有channel
        ConstantUtil.pushAll(message);
    }

    private static Map<String, String> getUrlParams(String url) {
        Map<String, String> map = new HashMap<>();
        url = url.replace("?", ";");
        if (!url.contains(";")) {
            return map;
        }
        if (url.split(";").length > 0) {
            String[] arr = url.split(";")[1].split("&");
            for (String s : arr) {
                String key = s.split("=")[0];
                String value = s.split("=")[1];
                map.put(key, value);
            }
            return map;

        } else {
            return map;
        }
    }
}
